using Moq;
using NUnit.Framework;
using Tycho.Grammar;
using Tycho.Language;
using Tycho.Parser.Peg;

namespace Tycho.UnitTests.Language {
    [TestFixture]
    public class ParserLoaderSpecification {
        [Test]
        public void ShouldLoadParser () {
            var lookup = new Mock<IProductionLookup> ();
            var productionCompiler = new Mock<IProductionCompiler> ();

            ITerm term = new Mock<ITerm> ().Object;
            IProduction production = new Mock<IProduction> ().Object;
            var grammarTree = new GrammarTree (production);

            IDynamicGrammar dynamicGrammar = new Mock<IDynamicGrammar> ().Object;
            productionCompiler.Setup (
                compiler =>
                compiler.Compile (term, null, It.Is<ProductionCompilerContext> (pcc => pcc.Lookup == lookup.Object && pcc.Grammar == dynamicGrammar)))
                .Returns (grammarTree);

            IParser expectedParser = new Mock<IParser> ().Object;

            var grammarTermLoader = new Mock<IGrammarParser> ();
            const string grammarSource = "source";
            grammarTermLoader.Setup (g => g.LoadGrammarTerms (grammarSource)).Returns (term);

            var dynamicParserCreator = new Mock<IDynamicParserCreator> ();
            dynamicParserCreator.Setup (d => d.CreateDynamicParser (dynamicGrammar, production)).Returns (expectedParser);
            var loader = new ParserLoader (grammarTermLoader.Object, () => lookup.Object, () => productionCompiler.Object, dynamicParserCreator.Object, () => dynamicGrammar);

            IParser parser = loader.LoadParser (grammarSource);

            Assert.That (parser, Is.EqualTo (expectedParser));
        }
    }
}